from django.db.models import CharField, ForeignKey, FloatField, IntegerField, BooleanField, CASCADE
from dvadmin.utils.models import CoreModel

TABLE_PREFIX = "iot_"
TEMP_TYPE = 'T'
VOLTAGE_TYPE = 'V'


class Cabinet(CoreModel):
    name = CharField(max_length=200, verbose_name='配电柜名称', null=False)
    code = CharField(max_length=200, verbose_name='配电柜编码', null=False)
    dept = ForeignKey(to='system.Dept', on_delete=CASCADE, verbose_name='所属部门', null=True)
    warm_early_warning = FloatField(verbose_name='预警值', null=True)
    warm_warning = FloatField(verbose_name='报警值', null=True)
    v_early_warning = FloatField(verbose_name='电压预警值', null=True)

    class Meta:
        db_table = TABLE_PREFIX + 'cabinet'
        verbose_name = '配电柜'
        verbose_name_plural = verbose_name
        ordering = ('code',)


class Gradation(CoreModel):
    name = CharField(max_length=200, verbose_name='名称', null=False)
    code = CharField(max_length=200, verbose_name='编码', null=False)

    class Meta:
        db_table = TABLE_PREFIX + 'gradation'
        verbose_name = '层级'
        verbose_name_plural = verbose_name


class Point(CoreModel):
    name = CharField(max_length=200, verbose_name='名称')
    code = CharField(max_length=200, verbose_name='编码')
    value = FloatField(verbose_name='当前值')
    is_warning = IntegerField(choices=((1, '报警'), (0, '预警'), (2, '正常')), verbose_name='当前报警状态', default=2)
    gradation = ForeignKey(to='Gradation', verbose_name='分层', on_delete=CASCADE, null=True)
    cabinet = ForeignKey(to='Cabinet', verbose_name='配电柜', on_delete=CASCADE)
    unit = ForeignKey(to='Unit', on_delete=CASCADE, verbose_name='单位', null=True)

    @classmethod
    def update(cls, code, **kwargs):
        point_queryset = cls.objects.filter(code=code)
        point_queryset.update(**kwargs)
        value = kwargs.get('value')
        point = point_queryset.first()
        if point.unit.type == TEMP_TYPE:
            if value >= point.cabinet.warm_early_warning and value < point.cabinet.warm_warning:
                point_queryset.update(**{'is_warning': 0})
                Warn.objects.filter(point=point).all().update(**{'is_handel': True})
                Warn.objects.create(point=point, **{'value': value, 'type': 0, 'dept_belong_id': point.dept_belong_id})
            elif value >= point.cabinet.warm_warning:
                point_queryset.update(**{'is_warning': 1})
                Warn.objects.filter(point=point).all().update(**{'is_handel': True})
                Warn.objects.create(point=point, **{'value': value, 'type': 1, 'dept_belong_id': point.dept_belong_id})
            else:
                Warn.objects.filter(point=point).all().update(**{'is_handel': True})
                point_queryset.update(**{'is_warning': 2})
        if point.unit.type == VOLTAGE_TYPE:
            if value < point.cabinet.v_early_warning:
                point_queryset.update(**{'is_warning': 1})
                Warn.objects.create(point=point, **{'value': value, 'type': 1, 'dept_belong_id': point.dept_belong_id})
            else:
                point_queryset.update(**{'is_warning': 2})

    class Meta:
        db_table = TABLE_PREFIX + 'point'
        verbose_name = '点位'
        verbose_name_plural = verbose_name


class Unit(CoreModel):
    name = CharField(max_length=200, verbose_name='单位名称')
    code = CharField(max_length=200, verbose_name='单位')
    type = CharField(max_length=200, verbose_name='类型备注', null=True)

    class Meta:
        db_table = TABLE_PREFIX + 'unit'
        verbose_name = '点位类型'
        verbose_name_plural = verbose_name


class Warn(CoreModel):
    point = ForeignKey(to='Point', on_delete=CASCADE, verbose_name='关联点位', null=False)
    type = IntegerField(choices=((1, '报警'), (0, '预警')), verbose_name='报警类型', default=0)
    value = FloatField(verbose_name='报警值')
    is_handel = BooleanField(verbose_name='是否处理', default=False)

    class Meta:
        db_table = TABLE_PREFIX + 'warn'
        verbose_name = '报警'
        verbose_name_plural = verbose_name
        ordering = ('-create_datetime',)
